﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Diagnostics;

namespace 图像处理多线程技术
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            myTimer = new HiPerfTimer();
        }
        private HiPerfTimer myTimer;
        private string curFileName;//文件名
        Bitmap curBitmap;//图像对象
        private void button1_Click_1(object sender, EventArgs e)
        {
            OpenFileDialog opnDlg = new OpenFileDialog();
            opnDlg.Filter = "所有图像文件 | *.bmp; *.pcx; *.png; *.jpg; *.gif;" +
                "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf|" +
                "位图( *.bmp; *.jpg; *.png;...) | *.bmp; *.pcx; *.png; *.jpg; *.gif; *.tif; *.ico|" +
                "矢量图( *.wmf; *.eps; *.emf;...) | *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf";
            opnDlg.Title = "打开图像文件";
            opnDlg.ShowHelp = true;
            if (opnDlg.ShowDialog() == DialogResult.OK)
            {
                curFileName = opnDlg.FileName;
                try
                {
                    curBitmap = (Bitmap)Image.FromFile(curFileName);
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message);
                }
            }
            pictureBox1.Invalidate();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (curBitmap == null) //如果没有创建图像，则退出
                return;
            SaveFileDialog saveDlg = new SaveFileDialog();//调用SaveFileDialog
            saveDlg.Title = "保存为";//设置对话框标题
            saveDlg.OverwritePrompt = true;//改写已存在文件是提醒用户
            saveDlg.Filter = "BMP文件(*.bmp)|*.bmp|" + "Gif文件(*.gif)|*.gif|" +
                "JPEG文件(*.jpg)|*.jpg|" + "PNG文件(*.png)|*.png";//为图像选择一个筛选器
            saveDlg.ShowHelp = true;//启用帮助按钮

            if (saveDlg.ShowDialog() == DialogResult.OK)//如果选择格式，则保存图像
            {
                string fileName = saveDlg.FileName;
                string strFilExtn = fileName.Remove(0, fileName.Length - 3);

                switch (strFilExtn)
                {
                    case "bmp":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Bmp);
                        break;
                    case "jpg":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                        break;
                    case "gif":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Gif);
                        break;
                    case "tif":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Tiff);
                        break;
                    case "png":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
                        break;
                    default:
                        break;

                }

            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (curBitmap != null)
            {
                g.DrawImage(curBitmap, 0, 0, 512, 512);
            }
        }

        private void button12_Click(object sender, EventArgs e)//高斯滤波
        {
            myTimer.ClearTimer();
            myTimer.Start();
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = bmpData.Width * bmpData.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            //double sigma = 1;
            double[] tempArray = new double[bytes];
            double[] tempImage = new double[bytes];
            //int rad = Convert.ToInt16(Math.Ceiling(3 * sigma));

            for (int i = 0; i < bytes-1; i++)
            {
                tempImage[i] = Convert.ToDouble(grayValues[i]);
            }
            //double std2 = 2 * sigma * sigma;//方差
            double std2 = 2;
            //int radius = Convert.ToInt16(Math.Ceiling(3 * sigma));//半径
            int radius = 3;
            //int filterWidth = 2 * radius + 1;
            int filterWidth = 7;
            double[] filter = new double[filterWidth];
            //double[] filter = new double[7];
            int length1 = bmpData.Width;
            int length2 = bmpData.Height;
            double sum = 0;
            for (int i = 0; i < filterWidth-1; i++)//产生一维高斯函数
            {
                int xx = (i - radius) * (i - radius);
                filter[i] = Math.Exp(-xx / std2);
                sum += filter[i];
            }
            for (int i = 0; i < filterWidth-1; i++)
            {
                filter[i] = filter[i] / sum;
            }

            for (int i = 0; i < length1-1; i++)//水平方向滤波
            {
                for (int j = 0; j < length2-1; j++)
                {
                    double temp = 0;
                    for (int k = -radius; k <= radius; k++)
                    {
                        int rem = (Math.Abs(j + k)) % length1;
                        temp += grayValues[i * length1 + rem] * filter[k + radius];
                    }
                    tempImage[i * length1 + j] = temp;
                }
            }
            for (int j = 0; j < length2-1; j++)//垂直方向滤波
            {
                for (int i = 0; i < length1-1; i++)
                {
                    double temp = 0;
                    for (int k = -radius; k <= radius; k++)
                    {
                        int rem = (Math.Abs(i + k)) % length2;
                        temp += tempImage[rem * length2 + j] * filter[k + radius];
                    }
                    tempArray[i * length2 + j] = temp;
                }
            }

            for (int i = 0; i < bytes-1; i++)
            {
                if (tempArray[i] > 255)
                    grayValues[i] = 255;
                else if (tempArray[i] < 0)
                    grayValues[i] = 0;
                else
                    grayValues[i] = Convert.ToByte(tempArray[i]);
            }

            myTimer.Stop();
            timeBox.Text = myTimer.Duration.ToString("####.##") + " 毫秒";
            Marshal.Copy(grayValues, 0, ptr, bytes);
            curBitmap.UnlockBits(bmpData);
            pictureBox1.Invalidate();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = curBitmap.Width * curBitmap.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double gradX, gradY, grad;
            double total=0;
            for (int i = 0; i < curBitmap.Height; i++)
            {
                for (int j = 0; j < curBitmap.Width; j++)
                {
                    gradX = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[i * curBitmap.Width + j];
                    gradY = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                    grad = gradX * gradX + gradY * gradY;
                    tempArray[i * curBitmap.Width + j] = grad;

                }
            }
            for (int i = 0; i < bytes; i++)
            {
                total +=tempArray[i];
            }
            textBox1.Text = Convert.ToString(total);
            textBox1.Text = textBox1.Text + "/" + Convert.ToString(total / curBitmap.Width / curBitmap.Height);
            curBitmap.UnlockBits(bmpData);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = curBitmap.Width * curBitmap.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double gradX, gradY, grad;
            double total = 0;
            for (int i = 0; i < curBitmap.Height; i++)
            {
                for (int j = 0; j < curBitmap.Width; j++)
                {
                    gradX = (grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j]+grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + grayValues[i * curBitmap.Width + j])/3-
                        (grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 2)) % curBitmap.Width)] + grayValues[grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 2)) % curBitmap.Width)] + grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 3)) % curBitmap.Width)]]) / 6 -
                        (grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] + grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] + grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)]) / 6;
                    gradY = (grayValues[i * curBitmap.Width +  ((Math.Abs(j - 1)) % curBitmap.Width)]+grayValues[i * curBitmap.Width + j] + grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)])/3-
                        (grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 3)) % curBitmap.Width)] + grayValues[grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 2)) % curBitmap.Width)] + grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]]) / 6 -
                        (grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] + grayValues[((i +2) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)]) / 6;
                    grad = gradX * gradX + gradY * gradY;
                    tempArray[i * curBitmap.Width + j] = grad;

                }
            }
            for (int i = 0; i < bytes; i++)
            {
                total+=tempArray[i];
            }
            textBox2.Text = Convert.ToString(total);
            textBox2.Text = textBox2.Text + "/" + Convert.ToString(total / curBitmap.Width / curBitmap.Height);
            curBitmap.UnlockBits(bmpData);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = curBitmap.Width * curBitmap.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double grad;
            double total = 0;
            for (int i = 0; i < curBitmap.Height; i++)
            {
                for (int j = 0; j < curBitmap.Width; j++)
                {
                    
                    grad = grayValues[i * curBitmap.Width + ((j + 2) % curBitmap.Width)]-grayValues[i * curBitmap.Width + j];
                    grad = grad * grad;
                    tempArray[i * curBitmap.Width + j] = grad;

                }
            }
            for (int i = 0; i < bytes; i++)
            {
                total +=tempArray[i];
            }
            textBox3.Text = Convert.ToString(total);
            textBox3.Text = textBox3.Text + "/" + Convert.ToString(total / curBitmap.Width / curBitmap.Height);
            curBitmap.UnlockBits(bmpData);
        }

        private void button7_Click(object sender, EventArgs e)//SML
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = curBitmap.Width * curBitmap.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double gradX, gradY, grad;
            double total = 0;
            for (int i = 1; i < curBitmap.Height-1; i++)
            {
                for (int j = 1; j < curBitmap.Width-1; j++)
                {

                    grad = Math.Abs(2 * grayValues[i * curBitmap.Width + j] - grayValues[i * curBitmap.Width + j - 1] - grayValues[i * curBitmap.Width + j + 1]) + 
                        Math.Abs(2 * grayValues[i * curBitmap.Width + j] - grayValues[(i - 1) * curBitmap.Width + j] - grayValues[(i + 1) * curBitmap.Width + j]);
                    tempArray[i * curBitmap.Width + j] = grad;
                    total +=tempArray[i * curBitmap.Width + j];
                }
            }

            textBox4.Text = Convert.ToString(total);
            textBox4.Text = textBox4.Text + "/" + Convert.ToString(total / curBitmap.Width / curBitmap.Height);
            curBitmap.UnlockBits(bmpData);
        }

        private void button9_Click(object sender, EventArgs e)//FSWM
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = curBitmap.Width * curBitmap.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double gradX, gradY, grad;
            double total = 0;
            for (int i = 0; i < curBitmap.Height; i++)
            {
                for (int j = 0; j < curBitmap.Width; j++)
                {
                    gradX = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[i * curBitmap.Width + j];
                    gradY = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                    grad = Math.Sqrt(gradX * gradX) + Math.Sqrt(gradY * gradY);
                    tempArray[i * curBitmap.Width + j] = grad;

                }
            }
            for (int i = 0; i < bytes; i++)
            {
                total +=tempArray[i];
            }
            textBox6.Text = Convert.ToString(total);
            textBox6.Text = textBox6.Text + "/" + Convert.ToString(total / curBitmap.Width / curBitmap.Height);
            curBitmap.UnlockBits(bmpData);
        }

        private void button8_Click(object sender, EventArgs e)//Tenengrad
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = curBitmap.Width * curBitmap.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double gradX, gradY, grad;
            double total = 0;
            for (int i = 0; i < curBitmap.Height; i++)
            {
                for (int j = 0; j < curBitmap.Width; j++)
                {
                    gradX = grayValues[((Math.Abs(i - 1)) % bmpData.Height) * bmpData.Width + ((j + 1) % (bmpData.Width ))] + 2 * grayValues[i * bmpData.Width  + ((j + 1) % (bmpData.Width ))] + grayValues[((i + 1) % bmpData.Height) * bmpData.Width + ((j + 1) % (bmpData.Width ))] -
                        grayValues[((Math.Abs(i - 1)) % bmpData.Height) * bmpData.Width  + ((Math.Abs(j - 1)) % (bmpData.Width ))] - 2 * grayValues[i * bmpData.Width  + ((Math.Abs(j - 1)) % (bmpData.Width ))] - grayValues[((i + 1) % bmpData.Height) * bmpData.Width  + ((Math.Abs(j - 1)) % (bmpData.Width ))];
                    gradY = grayValues[((Math.Abs(i - 1)) % bmpData.Height) * bmpData.Width + ((Math.Abs(j - 1)) % (bmpData.Width ))] + 2 * grayValues[((Math.Abs(i - 1)) % bmpData.Height) * bmpData.Width  + j] + grayValues[((Math.Abs(i - 1)) % bmpData.Height) * bmpData.Width  + ((j + 1) % (bmpData.Width ))] -
                        grayValues[((i + 1) % bmpData.Height) * bmpData.Width  + ((Math.Abs(j - 3)) % (bmpData.Width ))] - 2 * grayValues[((i + 1) % bmpData.Height) * bmpData.Width  + j] - grayValues[((i + 1) % bmpData.Height) * bmpData.Width + ((j + 1) % (bmpData.Width ))];
                    grad = gradX * gradX + gradY * gradY;
                    tempArray[i * curBitmap.Width + j] = grad;

                }
            }
            for (int i = 0; i < bytes; i++)
            {
                total +=tempArray[i];
            }
            textBox5.Text = Convert.ToString(total);
            textBox5.Text = textBox5.Text + "/" + Convert.ToString(total / curBitmap.Width / curBitmap.Height);
            curBitmap.UnlockBits(bmpData);
        }

        private void button10_Click(object sender, EventArgs e)//range
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = bmpData.Width * bmpData.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double gradX, gradY, grad;
            double total = 0;
            byte maxGray = 0;
            byte minGray = 255;
            int m = 0;
            int n = 0;
            for (int i = 0; i < bytes; i++)
            {
                byte temp = grayValues[i];
                
                if (temp > maxGray)
                {
                    maxGray = temp;
                }
                if (temp < minGray)
                {
                    minGray = temp;
                }
            }
            
            for (int i = 0; i < bytes; i++)
            {

                if (grayValues[i] == maxGray)
                {
                    m = m+1;
                }
                else if (grayValues[i] == minGray)
                {
                    n = n + 1;
                }
            }
            total = m * maxGray - n * minGray;
            textBox7.Text = Convert.ToString(total);
            textBox7.Text = textBox7.Text + "/" + Convert.ToString((int)(total / (m + n)));
            curBitmap.UnlockBits(bmpData);
        }

        private void button11_Click(object sender, EventArgs e)
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = curBitmap.Width * curBitmap.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double gradX, gradY, grad;
            double total = 0;
            for (int i = 0; i < curBitmap.Height; i++)
            {
                for (int j = 0; j < curBitmap.Width; j++)
                {

                    grad =grayValues[i * curBitmap.Width + j]* (Math.Abs(grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[i * curBitmap.Width + ((j + 2) % curBitmap.Width)]));
                    tempArray[i * curBitmap.Width + j] = grad;

                }
            }
            for (int i = 0; i < bytes; i++)
            {
                total +=tempArray[i];
            }
            textBox8.Text = Convert.ToString(total);
            textBox8.Text = textBox8.Text + "/" + Convert.ToString(total / curBitmap.Width / curBitmap.Height);
            curBitmap.UnlockBits(bmpData);
        }

        private void button13_Click(object sender, EventArgs e)
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = curBitmap.Width * curBitmap.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double u, grad;
            double total = 0;
            double total1 = 0;
            for (int i = 0; i < bytes; i++)
            {
                tempArray[i] = Convert.ToDouble(grayValues[i]);
                total += tempArray[i];
            }
            u = total / bytes;
           
            for (int i = 0; i < bytes; i++)
            {
                grad = (tempArray[i] - u) * (tempArray[i] - u);
                total1 += grad;
            }
            textBox9.Text = Convert.ToString(total);
            textBox9.Text = textBox9.Text + "/" + Convert.ToString(total / curBitmap.Width / curBitmap.Height);
            curBitmap.UnlockBits(bmpData);
        }

        private void button14_Click(object sender, EventArgs e)
        {
            if (this.curBitmap != null)
            {
                int Height = curBitmap.Height;
                int Width = curBitmap.Width;
                Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
                Bitmap MyBitmap = (Bitmap)curBitmap;
                BitmapData oldData = MyBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                BitmapData newData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                IntPtr ptr = oldData.Scan0;
                int bytes = oldData.Width * oldData.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                double total = 0;
                unsafe
                {
                    //边缘清晰度算法
                    byte* pointerBefore = (byte*)(oldData.Scan0.ToPointer());
                    byte* pointerAfter = pointerBefore + (oldData.Stride);
                    byte* pouter = (byte*)(newData.Scan0.ToPointer());
                    for (int y = 0; y < oldData.Height - 1; y++)
                    {
                        for (int x = 0; x < oldData.Width; x++)
                        {
                            double b = System.Math.Sqrt(
                                Math.Pow((double)pointerBefore[0] - (double)(pointerAfter[0] + 3), 2)
                                + Math.Pow((double)(pointerBefore[0] + 3) - (double)pointerAfter[0], 2)
                                );
                            double g = System.Math.Sqrt(
                                Math.Pow((double)pointerBefore[1] - (double)(pointerAfter[1] + 3), 2)
                                + Math.Pow((double)(pointerBefore[1] + 3) - (double)pointerAfter[1], 2)
                                );
                            double r = System.Math.Sqrt(
                                Math.Pow((double)pointerBefore[2] - (double)(pointerAfter[2] + 3), 2)
                                + Math.Pow((double)(pointerBefore[2] + 3) - (double)pointerAfter[2], 2)
                                );
                            double bgr = b + g + r;
                            if (bgr > 60)//边缘阈值
                            {
                                b = 255; g = 255; r = 255;
                                total += 255 * 3;
                            }
                            else
                            {
                                b = 0; g = 0; r = 0;
                            }
                            pouter[0] = (byte)(b);
                            pouter[1] = (byte)(g);
                            pouter[2] = (byte)(r);
                            pointerBefore = pointerBefore + 3;
                            pointerAfter = pointerAfter + 3;
                            pouter = pouter + 3;

                        }
                        pointerBefore += oldData.Stride - oldData.Width * 3;
                        pointerAfter += oldData.Stride - oldData.Width * 3;
                        pouter += newData.Stride - newData.Width * 3;
                    }


                    byte* pinD = (byte*)(newData.Scan0.ToPointer());
                    int times = 0;
                    for (int y = 0; y < oldData.Height - 3; y++)
                    {
                        if (y < 6 || (y >= (int)(oldData.Height * 0.05) && y <= (int)(oldData.Height * 0.95)))
                        {
                            pinD += 3 * newData.Width;
                            pinD += newData.Stride - newData.Width * 3;
                            continue;
                        }

                        int rownum = 0;
                        for (int x = 3; x < oldData.Width - 3; x++)
                        {
                            if ((pinD[0] == 255 && pinD[1] == 255 && pinD[2] == 255))
                            {
                                rownum += 1;
                            }
                            else
                            {
                                for (int j = 1; j <= 3; j++)
                                {
                                    byte* after = pinD + (newData.Stride - newData.Width * 3) * j;
                                    byte* before = pinD - (newData.Stride - newData.Width * 3) * j;
                                    if ((after[0] == 255 && after[1] == 255 && after[2] == 255)
                                        || (before[0] == 255 && before[1] == 255 && before[2] == 255)
                                        )
                                    {
                                        rownum += 1;
                                        j = 3;
                                    }
                                }
                            }
                            pinD += 3;
                        }
                        if ((double)rownum / oldData.Width > 0.3)
                        {
                            //txt_margin.Text += (int)(((double)rownum / oldData.Width)*100) + ";";
                            times += 1;
                        }
                        pinD += newData.Stride - newData.Width * 3;
                    }
                    //边缘清晰度标准差
                    int totalKey = (int)(total / (curBitmap.Height) / (curBitmap.Width));
                    textBox10.Text = "";
                    txt_recapture.Text = "";
                    if (totalKey <= 20 || (times >= 1 && times <= 6))
                    {
                        txt_recapture.Text = "翻拍-不清晰";
                    }
                    else
                    {
                        txt_recapture.Text = "清晰";
                    }
                    textBox10.Text = textBox10.Text + "边缘清晰度标准差:" + totalKey;
                    if (times >= 1 && times <= 6)
                    {
                        textBox10.Text = textBox10.Text + ";手机框" + times + "次;";
                    }

                    /*byte* pinA = (byte*)(newData.Scan0.ToPointer());
                    for (int y = 0; y < oldData.Height - 3; y++)
                    {
                        for (int x = 3; x < oldData.Width-3; x++)
                        {
                            if (pinA[0] == 255 && pinA[1] == 255 && pinA[2] == 255)
                            {
                                pinA[-3] = 255;pinA[-2] = 255;pinA[-1] = 255;                                                    
                            }
                            pinA += 3;
                        }
                        pinA += newData.Stride - newData.Width * 3;
                    }*/
                    /*byte* pinB = (byte*)(oldData.Scan0.ToPointer());
                     byte* pinC = (byte*)(newData.Scan0.ToPointer());
                     for (int y = 0; y < oldData.Height - 1; y++)
                     {
                         for (int x = 0; x < oldData.Width; x++)
                         {
                             if (pinC[0] == 255 && pinC[1] == 255 && pinC[2] == 255)
                             {
                                 pinC[0] = pinB[0];pinC[1] = pinB[1];pinC[2] = pinB[2];
                             }
                             pinB += 3;
                             pinC += 3;
                         }
                         pinB += oldData.Stride - oldData.Width * 3;
                         pinC += newData.Stride - newData.Width * 3;
                     }*/
                    bitmap.UnlockBits(newData);
                    MyBitmap.UnlockBits(oldData);
                    this.pic_margin.Image = bitmap;
                    pic_margin.Visible = true;
                }

            } 
        }

        private void but_moire_Click(object sender, EventArgs e)
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = bmpData.Width * bmpData.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double gradX, gradY, grad;
            double total = 0;
            byte maxGray = 0;
            byte minGray = 255;
            int m = 0;
            int n = 0;

            for (int i = 0; i < curBitmap.Height - 1; i++)
            {
                for (int j = 0; j < curBitmap.Width-1; j++)
                {
                    double beforeTotal=total;
                    total += Math.Sqrt(
                        (Math.Pow(
                        grayValues[(i+1) * curBitmap.Width + j] - grayValues[i * curBitmap.Width + j], 2) 
                        + Math.Pow(
                        grayValues[i * curBitmap.Width + j + 1] - grayValues[i * curBitmap.Width + j], 2))
                        );
                    total += Math.Abs(
                        grayValues[(i + 1) * curBitmap.Width + j] - grayValues[i * curBitmap.Width + j]
                        ) 
                        +
                        Math.Abs(
                        grayValues[i * curBitmap.Width + j + 1] - grayValues[i * curBitmap.Width + j]
                        );

                    grayValues[i * curBitmap.Width + j] = (byte)(int)(total - beforeTotal);
                }
            }

            //total = total / (curBitmap.Height * curBitmap.Width);
            txt_moire.Text = Convert.ToString((int)total);
            txt_moire.Text = txt_moire.Text + "/" + Convert.ToString((int)(total / (curBitmap.Height * curBitmap.Width)));
            curBitmap.UnlockBits(bmpData);
        }

        private void btn_light_Click(object sender, EventArgs e)
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = bmpData.Width * bmpData.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double gradX, gradY, grad;
            double total = 0;
            byte maxGray = 0;
            byte minGray = 255;
            int m = 0;
            int n = 0;

            for (int i = 0; i < bytes; i++)
            {
                total += (double)grayValues[i];
            }

            //total = total / (curBitmap.Height * curBitmap.Width);
            txt_light.Text = Convert.ToString((int)total);
            txt_light.Text = txt_light.Text + "/" + Convert.ToString((int)(total / (curBitmap.Height * curBitmap.Width)));
            curBitmap.UnlockBits(bmpData);
            Color col = curBitmap.GetPixel(1, 1);
        }

        private void btn_colour_Click(object sender, EventArgs e)
        {
            double totalRed = 0;
            double totalBlue = 0;
            double totalGreen = 0;
            double totalAlpha = 0;
            for (int i = 0; i < curBitmap.Width; i++)
            {
                for (int j = 0; j < curBitmap.Height; j++)
                {
                    Color col = curBitmap.GetPixel(i, j);
                    totalRed += (double)col.R;
                    totalBlue += (double)col.B;
                    totalGreen += (double)col.G;
                    totalAlpha += (double)col.A;
                }
            }
            int avgAlpha = (int)(totalAlpha / (curBitmap.Height * curBitmap.Width));
            int avgRed = (int)(totalRed / (curBitmap.Height * curBitmap.Width));
            int avgBlue = (int)(totalBlue / (curBitmap.Height * curBitmap.Width));
            int avgGreen=(int)(totalGreen / (curBitmap.Height * curBitmap.Width));
            int totleAvg = avgRed + avgBlue + avgGreen;
            txt_colour.Text = "R:B:G=" + Math.Round((double)avgRed / (double)totleAvg,2) + ":" +  Math.Round((double)avgBlue / (double)totleAvg,2) + ":" +  Math.Round((double)avgGreen / (double)totleAvg,2);
            txt_colour.Text = txt_colour.Text + "/" + Convert.ToString((int)(totalRed / (curBitmap.Height * curBitmap.Width)));
            txt_colour.Text = txt_colour.Text + "/" + Convert.ToString((int)(totalBlue / (curBitmap.Height * curBitmap.Width)));
            txt_colour.Text = txt_colour.Text + "/" + Convert.ToString((int)(totalGreen / (curBitmap.Height * curBitmap.Width))); 
        }

        private void btn_Sharpness_Click(object sender, EventArgs e)
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = bmpData.Width * bmpData.Height;
            byte[] grayValues = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
            double[] tempArray = new double[bytes];
            double total = 0;
            for (int i = 1; i < curBitmap.Height - 1; i++)
            {
                for (int j = 1; j < curBitmap.Width - 1; j++)
                {

                    total += Math.Abs(
                        (grayValues[(i - 1) * curBitmap.Width + (j - 1)] - grayValues[i * curBitmap.Width + j]) * 0.7
                        + (grayValues[(i - 1) * curBitmap.Width + j] - grayValues[i * curBitmap.Width + j])
                        + (grayValues[(i - 1) * curBitmap.Width + (j + 1)] - grayValues[i * curBitmap.Width + j]) * 0.7
                        + (grayValues[i * curBitmap.Width + (j - 1)] - grayValues[i * curBitmap.Width + j])
                        + (grayValues[i * curBitmap.Width + (j + 1)] - grayValues[i * curBitmap.Width + j])
                        + (grayValues[(i + 1) * curBitmap.Width + (j - 1)] - grayValues[i * curBitmap.Width + j]) * 0.7
                        + (grayValues[(i + 1) * curBitmap.Width + j] - grayValues[i * curBitmap.Width + j])
                        + (grayValues[(i + 1) * curBitmap.Width + (j + 1)] - grayValues[i * curBitmap.Width + j]) * 0.7);

                }
            }
            curBitmap.UnlockBits(bmpData);
            txt_Sharpness.Text = Convert.ToString((int)total);
            txt_Sharpness.Text = txt_Sharpness.Text + "/" + Convert.ToString((int)(total / (curBitmap.Height - 2) / (curBitmap.Width - 2)));
        }

        private void btn_margin_Click(object sender, EventArgs e)
        {
            if (this.curBitmap != null)
            {
                int Height = curBitmap.Height;
                int Width = curBitmap.Width;
                Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
                Bitmap MyBitmap = (Bitmap)curBitmap;
                BitmapData oldData = MyBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
                BitmapData newData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
                IntPtr ptr = oldData.Scan0;
                int bytes = oldData.Width * oldData.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                double total = 0;
                unsafe
                {
                    //边缘清晰度算法
                    byte* pointerBefore = (byte*)(oldData.Scan0.ToPointer());
                    byte* pointerAfter = pointerBefore + (oldData.Stride);
                    byte* pouter = (byte*)(newData.Scan0.ToPointer());
                    for (int y = 0; y < oldData.Height - 1; y++)
                    {
                        for (int x = 0; x < oldData.Width; x++)
                        {
                            double b = System.Math.Sqrt(
                                Math.Pow((double)pointerBefore[0] - (double)(pointerAfter[0] + 3),2)
                                + Math.Pow((double)(pointerBefore[0] + 3) - (double)pointerAfter[0],2)
                                );
                            double g = System.Math.Sqrt(
                                Math.Pow((double)pointerBefore[1] - (double)(pointerAfter[1] + 3),2)
                                + Math.Pow((double)(pointerBefore[1] + 3) - (double)pointerAfter[1],2)
                                );
                            double r = System.Math.Sqrt(
                                Math.Pow((double)pointerBefore[2] - (double)(pointerAfter[2] + 3),2)
                                + Math.Pow((double)(pointerBefore[2] + 3) - (double)pointerAfter[2],2)
                                );
                            double bgr = b + g + r;
                            if (bgr > 60)
                            {
                                b = 255;g = 255;r = 255;
                                total += 255 * 3;
                            }
                            else
                            {
                                b = 0;g = 0;r = 0;
                            }
                            pouter[0] = (byte)(b);
                            pouter[1] = (byte)(g);
                            pouter[2] = (byte)(r);
                            pointerBefore = pointerBefore + 3;
                            pointerAfter = pointerAfter + 3;
                            pouter = pouter + 3;

                        }
                        pointerBefore += oldData.Stride - oldData.Width * 3;
                        pointerAfter += oldData.Stride - oldData.Width * 3;
                        pouter += newData.Stride - newData.Width * 3;
                    }

                   
                    byte* pinD = (byte*)(newData.Scan0.ToPointer());
                    int times = 0;
                    for (int y = 0; y < oldData.Height - 3; y++)
                    {
                        if (y < 6 ||( y >= (int)(oldData.Height * 0.05) && y <= (int)(oldData.Height * 0.95)))
                        {
                            pinD += 3 * newData.Width;
                            pinD += newData.Stride - newData.Width * 3;
                            continue;
                        }

                        int rownum = 0;
                        for (int x = 3; x < oldData.Width - 3; x++)
                        {
                            if ((pinD[0] == 255 && pinD[1] == 255 && pinD[2] == 255))
                            {
                                rownum += 1;
                            }
                            else {
                               for (int j = 1; j <= 3; j++) {
                                    byte* after = pinD + (newData.Stride - newData.Width * 3) * j;
                                    byte* before = pinD - (newData.Stride - newData.Width * 3) * j;
                                    if ((after[0] == 255 && after[1] == 255 && after[2] == 255)
                                        ||(before[0] == 255 && before[1] == 255 && before[2] == 255)
                                        ) {
                                        rownum += 1;
                                        j = 3;
                                    }
                                }
                            }
                            pinD += 3;
                        }
                        if ((double)rownum / oldData.Width > 0.3)
                        {
                            //txt_margin.Text += (int)(((double)rownum / oldData.Width)*100) + ";";
                            times += 1;
                        }
                        pinD += newData.Stride - newData.Width * 3;
                    }
                    //txt_margin.Text += Convert.ToString((int)total);
                    txt_margin.Text = "";
                    //边缘清晰度标准差
                    txt_margin.Text = txt_margin.Text + "/" + Convert.ToString((int)(total / (curBitmap.Height) / (curBitmap.Width)));
                    if (times >= 1 && times <= 6)
                    {
                        txt_margin.Text = txt_margin.Text + ";手机框" + times+"次";
                    }
                    /*byte* pinA = (byte*)(newData.Scan0.ToPointer());
                    for (int y = 0; y < oldData.Height - 3; y++)
                    {
                        for (int x = 3; x < oldData.Width-3; x++)
                        {
                            if (pinA[0] == 255 && pinA[1] == 255 && pinA[2] == 255)
                            {
                                pinA[-3] = 255;pinA[-2] = 255;pinA[-1] = 255;                                                    
                            }
                            pinA += 3;
                        }
                        pinA += newData.Stride - newData.Width * 3;
                    }*/
                    /*byte* pinB = (byte*)(oldData.Scan0.ToPointer());
                     byte* pinC = (byte*)(newData.Scan0.ToPointer());
                     for (int y = 0; y < oldData.Height - 1; y++)
                     {
                         for (int x = 0; x < oldData.Width; x++)
                         {
                             if (pinC[0] == 255 && pinC[1] == 255 && pinC[2] == 255)
                             {
                                 pinC[0] = pinB[0];pinC[1] = pinB[1];pinC[2] = pinB[2];
                             }
                             pinB += 3;
                             pinC += 3;
                         }
                         pinB += oldData.Stride - oldData.Width * 3;
                         pinC += newData.Stride - newData.Width * 3;
                     }*/
                    bitmap.UnlockBits(newData);
                    MyBitmap.UnlockBits(oldData);
                    this.pic_margin.Image = bitmap;
                    pic_margin.Visible = true;
                }

            }
        }

        private void button14_Click_1(object sender, EventArgs e)
        {
            if (pic_margin.Image == null) //如果没有创建图像，则退出
                return;
            SaveFileDialog saveDlg = new SaveFileDialog();//调用SaveFileDialog
            saveDlg.Title = "保存为";//设置对话框标题
            saveDlg.OverwritePrompt = true;//改写已存在文件是提醒用户
            saveDlg.Filter = "BMP文件(*.bmp)|*.bmp|" + "Gif文件(*.gif)|*.gif|" +
                "JPEG文件(*.jpg)|*.jpg|" + "PNG文件(*.png)|*.png";//为图像选择一个筛选器
            saveDlg.ShowHelp = true;//启用帮助按钮

            if (saveDlg.ShowDialog() == DialogResult.OK)//如果选择格式，则保存图像
            {
                string fileName = saveDlg.FileName;
                string strFilExtn = fileName.Remove(0, fileName.Length - 3);

                switch (strFilExtn)
                {
                    case "bmp":
                        pic_margin.Image.Save(fileName, System.Drawing.Imaging.ImageFormat.Bmp);
                        break;
                    case "jpg":
                        pic_margin.Image.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                        break;
                    case "gif":
                        pic_margin.Image.Save(fileName, System.Drawing.Imaging.ImageFormat.Gif);
                        break;
                    case "tif":
                        pic_margin.Image.Save(fileName, System.Drawing.Imaging.ImageFormat.Tiff);
                        break;
                    case "png":
                        pic_margin.Image.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
                        break;
                    default:
                        break;

                }

            }
        }
    }
}

